﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.InteropServices;
using System.Xml.Serialization;
using Microsoft.Office.Interop.Excel;

namespace ObjectModel.Excel
{
    /// <summary>
    /// An Excel workbook object that can resolve itself from serializable info.
    /// </summary>
    public class ResolvableWorkbook
    {
        bool mOpenedProgrammatically = false;
        FileInfo mWbFileInfo;

        Application App { get { return Globals.Application; } }

        // Needed to get a reference to a workbook object that is already open in the current app.
        [XmlIgnore]
        public string Name
        {
            get { return mWbFileInfo.Name; }
        }

        // Needed to get a reference to a workbook object that is currently not open.
        public string FullName // To be serialized. Must be public.
        {
            get { return mWbFileInfo == null ? string.Empty : mWbFileInfo.FullName; }
            set
            {
                if (!string.IsNullOrEmpty(value))
                    mWbFileInfo = new FileInfo(value);
            }
        }

        [XmlIgnore]
        public bool OpenedProgrammatically
        {
            get { return mOpenedProgrammatically; }
        }

        public ResolvableWorkbook() { } // Parameterless constructor required for serialization.

        public ResolvableWorkbook(Workbook wb) : this(wb.FullName) { }

        public ResolvableWorkbook(string wbFullName)
        {
            FullName = wbFullName;
        }

        public Workbook Resolve()
        {
            Workbook wb = null;
            mOpenedProgrammatically = false;

            // First assume the workbook is open and try and find it in the current app.
            try { wb = App.Workbooks[Name]; }
            catch (COMException)
            {
                // Look for the workbook in the file system and open in the current app.
                if (File.Exists(FullName))
                {
                    try
                    {
                        wb = App.Workbooks.Open(FullName, System.Type.Missing, true); // Open workbook as read-only
                        mOpenedProgrammatically = true;
                    }
                    catch (COMException) { throw new InvalidOperationException(FullName + " cannot be opened."); }
                }
                else
                    throw new InvalidOperationException(FullName + " does not exist.");
            }

            return wb;
        }

        public void Close()
        {
            try { App.Workbooks[Name].Close(); }
            catch (COMException) { }
        }
    }
}
